<!--
    固定表头；列表
-->
<template>
	<div class="table-wrapper table-fixed table-fiexd-action"
	     :class="{unselect:unselect}"
	     @contextmenu="onContextmenu">
		<Spin size="large"
		      fix
		      v-show="loading"></Spin>
		<div class="table-header-wrapper">
			<div class="table-header-box"
			     ref="header_box"
			     :style="{'margin-right':hasData?(actionWidth||scrollerWidth)+'px':0}">
				<table class="table table-header"
				       ref="header_table"
				       :style="{width:headerWidth}">
					<colgroup>
						<col :width="checkWith"
						     v-if="hasCheck"></col>
						<col v-for="(item,index) in widthList"
						     :width="item"
						     :key="index"></col>
					</colgroup>
					<tbody>
						<tr>
							<th class="check-cell header-item"
							    @click="checkAllRow($event)"
							    v-if="hasCheck">
								<Checkbox v-show="!singleSelect"
								          v-model="checkAll"></Checkbox>
							</th>
							<th class="header-item"
							    v-for="(col,index) in orderFields"
							    :key="index"
							    ref="header"
							    :title="col.code+' '+col.name"
							    v-if="col.listpos!==false"
							    :data-code="col.code">
								{{col.name}}
							</th>
						</tr>
					</tbody>
				</table>
			</div>
			<div v-if="actionShow && hasInlineAction"
			     class="table-header-action header-item"
			     :style="{width:actionWidth+'px'}">操作</div>
		</div>
		<div class="table-content-wrapper"
		     ref="table_wrapper">
			<div class="table-data-wrapper"
			     ref="table_data">
				<table ref="data_table"
				       class="table"
				       :class="tableClass"
				       :style="dataTableStyle">
					<colgroup>
						<col :width="checkWith"
						     v-if="hasCheck"></col>
						<col v-for="(item,index) in widthList"
						     :width="item"
						     :key="index"></col>
						<col></col>
					</colgroup>
					<tbody>
						<slot name="tbody">
							<tr v-if="!tableData || !tableData.length">
								<td colspan="999"
								    class="text-nodata">
									暂无数据
								</td>
							</tr>
							<tr v-else
							    @dblclick="dbTrigger(index)"
							    v-for="(row,index) in tableData"
							    :key="row.id"
							    :style="rowsStyle[index]"
							    :class="{[ativeClass]:checkList[index]}"
							    @click="checkTableRow($event,index)">
								<td class="check-cell"
								    v-if="hasCheck"
								    @click="checkRow($event,index)">
									<Checkbox v-model="checkList[index]"></Checkbox>
								</td>
								<td v-for="col in orderFields"
								    :key="col.code"
								    v-if="col.listpos!==false">
									<div class="field-container">
										<div v-if="!extRender[col.code]"
										     v-height-light="col.rangeset && col.rangeset.lang"
										     class="field"
										     :class="fieldClass(row[col.code],col.code)"
										     v-html="renderData(row[col.code],col.code,row)"></div>
										<component v-else-if="extRender[col.code].component"
										           :is="extRender[col.code].component"
										           :data="row[col.code]"
										           :field="col"
										           :row="row"
										           :option="extRender[col.code]"
										           :index="index"
										           :model="col"></component>
										<div class="copy-tip"
										     v-if="col.param && col.param.enable_copy">
											<Icon type="ios-copy"></Icon>
										</div>
									</div>
								</td>
							</tr>
						</slot>
					</tbody>
					<tfoot v-if="false">
						<slot name="tfoot">
							<th></th>
						</slot>
					</tfoot>
				</table>
			</div>
			<div class="table-action-wrapper"
			     v-if="hasInlineAction && actionShow">
				<table ref="action_table"
				       v-if="actionShow"
				       class="table table-action"
				       :class="tableClass">
					<tbody>
						<tr v-for="(row,index) in tableData"
						    :key="row.id"
						    :style="rowsStyle[index]"
						    :class="{[ativeClass]:checkList[index]}"
						    @click="checkTableRow($event,index)">
							<td v-if="tableModel.actions && tableModel.actions.length">
								<div class="text-right">
									<InlineAction v-show="inlineActionStatus[action.code]?inlineActionStatus[action.code].show:true"
									              v-for="action in tableModel.actions"
									              :index="index"
									              :model="action"
									              :key="action.code"
									              :row="row"></InlineAction>
								</div>
							</td>
						</tr>
					</tbody>
				</table>
			</div>
			<Scroller class="scroll-bottom"
			          :contentWidth="tableWidth+(actionWidth||0)"
			          @scrollChange="scrollLeftChange"
			          :axisX="scrollLeft"
			          :style="{'right':(scrollerWidth||0)+'px'}"></Scroller>
		</div>
	</div>
</template>
<script>
/**
    固定头部开发记录
    通过同步col来保障头部与底部高度相同
    需要处理的是通过逐个比较单元格最大宽度的决定最终的宽度
    当col中width总值超过列表宽度时，浏览器将会根据内容调整单元格的实际宽度，导致表头与表体无法对应

    TODO
    初始化表头时可以先记录表头的最小宽度，进行缓存在，表头改变时在进行重新获取，可以防止无数据时表头自动填充，影响到后面数据填充时字段宽度的计算
     */
import gridTable from './gridTableSample';
export default {
	name: 'fixTable',
	extends: gridTable,
	data() {
		return {
			//列宽度列表
			widthList: [],
			//数据横向滚动值
			scrollWidth: 0,
			//滚动条宽度
			scrollerWidth: 0,
			scrollLeft: 0,
			//选择栏宽度
			checkWith: null,
			//数据列表宽度
			tableWidth: null,
			//操作栏宽度
			actionWidth: null,
			headerMark: false,
			tableDataWidthCatch: 0,
		};
	},
	computed: {
		dataTableStyle() {
			if (this.tableWidth) {
				return {
					width: this.tableWidth + 'px',
				};
			} else {
				if (!this.hasData) {
					return {
						width: '100%',
					};
				}
			}
		},
		headerWidth() {
			if (this.hasData && this.tableWidth) {
				return this.tableWidth + 'px';
			} else {
				return this.headerMark ? '100%' : 'auto';
			}
		},
	},
	watch: {
		tableWidth(v) {
			this.$nextTick(() => {
				if (this.tableDataWidthCatch === 0 && v < this.$refs.table_data.offsetWidth) {
					this.updateColumnsStyle();
				}
			});
		},
		//额外渲染属性变化时重新计算宽度
		extRender() {
			this.$nextTick(() => {
				this.updateColumnsStyle();
			});
		},
	},
	methods: {
		updateTableStyle() {
			this.updateColumnsStyle();
		},
		updateColumnsStyle() {
			this.tableWidth = null;
			if (!this.hasData) {
				this.headerMark = true;
				return;
			} else {
				this.headerMark = false;
			}
			this.$nextTick(() => {
				this.updateColumnsStyleProcess();
				//临时方案，待完善
				this.$nextTick(() => {
					this.updateRowStyle();
				});
			});
		},
		updateColumnsStyleProcess() {
			var list = [];
			var widthCounter = 0;
			var wrapperWidth = this.$refs.table_data.offsetWidth;
			this.tableDataWidthCatch = wrapperWidth;
			this.scrollerWidth = this.$refs.table_wrapper.offsetWidth - this.$refs.table_wrapper.clientWidth;
			//通过offsetWidth和clientWidth计算出滚动条宽度，添加到操作栏的宽度上
			if (this.$refs.action_table) {
				this.actionWidth = this.$refs.action_table.offsetWidth + this.scrollerWidth;
			}
			this.getRowsElement();
			if (this.dataRows && this.dataRows[0] && this.tableData.length && this.$refs.header) {
				var tds = this.dataRows[0].children;
				//根据是否存在checkbox判断错位
				var checkFixed = this.hasCheck ? 1 : 0;
				//比较表头与表体的单元格宽度，记到最终的单元格宽度
				Array.prototype.forEach.call(this.$refs.header, (item, index) => {
					list[index] = Math.max(tds[index + checkFixed].offsetWidth, item.offsetWidth);
					widthCounter += list[index];
				});
				if (this.hasCheck) {
					//获取选择栏宽度
					this.checkWith = tds[0].clientWidth;
					//累计最终单元格宽度
					widthCounter += this.checkWith || 0;
				}
			}
			//若最终宽度小于容器宽度，则自动填充
			if (widthCounter < wrapperWidth) {
				this.tableWidth = wrapperWidth;
			} else {
				this.tableWidth = widthCounter;
			}
			this.$set(this, 'widthList', list);
		},
		tableScroll(name) {
			let el = this.$refs.table_data;
			if (el) {
				this.scrollLeft = el.scrollLeft / (el.scrollWidth - el.offsetWidth);
			}
		},
		scrollLeftChange(v) {
			let el = this.$refs.table_data;
			if (el) {
				el.scrollLeft = (el.scrollWidth - el.offsetWidth) * (v / 100);
			}
		},
		//右键菜单时间
		onContextmenu(e) {
			if (this.unselect) {
				e.returnValue = false;
			}
		},
	},
	mounted() {
		this.resizeHandler = () => {
			this.updateColumnsStyle();
		};
		this.$refs.table_data.addEventListener('scroll', e => {
			var table = e.target;
			var header = this.$refs.header_box;
			if (header) {
				header.scrollTo(header.scrollWidth * (table.scrollLeft / table.scrollWidth), header.scrollTop);
			}
		});
		//窗口调整重新计算宽度
		window.addEventListener('resize', this.resizeHandler);
	},
	destroyed() {
		window.removeEventListener('resize', this.resizeHandler);
	},
};
</script>

<style lang="less">
.table-wrapper.table-fixed {
	overflow: hidden;
	height: 100%;
	overflow: hidden;
	min-height: 200px;
	flex-direction: column;
	padding-bottom: 0;
	table {
		transition: all 0.3s;
	}
	.scroll-bottom {
		position: absolute;
		z-index: 20;
		bottom: 0;
	}
	.table-content-wrapper {
		display: flex;
		flex: 1 1 auto;
		overflow-y: auto;
		.table-data-wrapper {
			overflow-y: hidden;
			overflow-x: hidden;
			height: 100%;
			> .table {
				width: auto;
			}
		}
	}
	.table-action-wrapper {
		box-shadow: none;
		.table {
			box-shadow: 3px 0px 12px rgba(112, 112, 112, 0.5);
		}
	}
	.data-time {
		text-align: left;
	}
	.table-header-wrapper {
		width: 100%;
		position: relative;
		box-shadow: 8px 0px 4px rgba(112, 112, 112, 0.5);
		background: #f3f3f3;
		border-top: 1px solid #dddee1;
		border-bottom: 1px solid #dddee1;
		tr:hover {
			background: #f9f9f9;
			th {
				background: #f9f9f9;
			}
		}
		.table {
			border-top: none;
			border-bottom: none;
		}
	}
	.table-header-box {
		flex: 1;
		overflow: hidden;
		border-right: 1px solid #dddee1;
	}
	.table-header-action {
		border-right: 1px solid #dddee1;
		box-shadow: 3px 0px 12px rgba(112, 112, 112, 0.5);
		position: absolute;
		right: 0;
		top: 0;
	}
	.table-header {
		width: auto;
		border-collapse: collapse;
		position: relative;
	}
	.header-item {
		transition: background-color 0.2s ease-in-out;
		min-width: 0;
		height: auto;
		box-sizing: border-box;
		text-align: left;
		text-overflow: ellipsis;
		vertical-align: middle;
		padding: 8px 8px;
		max-width: 400px;
		white-space: nowrap;
		background-color: rgb(243, 243, 243);
		&.check-cell {
			width: 32px;
			padding-right: 0px;
			cursor: pointer;
		}
	}
}
</style>
